This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.
When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
tickers <- c("NVDA", "AMD", "AC")
getSymbols(tickers, from = "2016-01-01", to = Sys.Date(), src = "yahoo")
## [1] "NVDA" "AMD" "AC"
prices <- do.call(merge, lapply(tickers, function(x) Ad(get(x))))
colnames(prices) <- tickers
returns <- na.omit(ROC(prices, type = "discrete"))
# Descargar datos del IPC
getSymbols("^MXX", from = "2016-01-01", to = Sys.Date(), src = "yahoo")
## [1] "MXX"
ipc_prices <- Ad(MXX)
ipc_returns <- na.omit(ROC(ipc_prices, type = "discrete"))
# Calcular estadísticas para cada acción
stats <- function(ticker) {
data <- na.omit(ROC(Ad(get(ticker)), type = "discrete"))
list(
Min = min(data),
Max = max(data),
Mean = mean(data),
Variance = var(data),
SharpeRatio = SharpeRatio.annualized(data, Rf = 0.01/252),
Beta = CAPM.beta(data, ipc_returns, Rf = 0.01/252)
)
}
stats_list <- lapply(tickers, stats)
stats_df <- do.call(rbind, lapply(stats_list, function(x) unlist(x)))
rownames(stats_df) <- tickers
colnames(stats_df) <- c("Min", "Max", "Mean", "Variance", "SharpeRatio", "Beta")
kable(stats_df, format = "html", table.attr = "class='table table-striped'") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
| Min | Max | Mean | Variance | SharpeRatio | Beta | |
|---|---|---|---|---|---|---|
| NVDA | -0.1875586 | 0.2980669 | 0.0028716 | 0.0009818 | 1.618666 | 0.7352442 |
| AMD | -0.2422908 | 0.5229008 | 0.0025977 | 0.0014125 | 1.007883 | 0.8870997 |
| AC | -0.1726670 | 0.4881807 | 0.0004002 | 0.0006386 | 0.034003 | 0.5018103 |
cov_matrix <- cov(returns)
kable(cov_matrix, format = "html", table.attr = "class='table table-striped'") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
| NVDA | AMD | AC | |
|---|---|---|---|
| NVDA | 0.0009818 | 0.0007153 | 0.0001679 |
| AMD | 0.0007153 | 0.0014125 | 0.0001781 |
| AC | 0.0001679 | 0.0001781 | 0.0006386 |
print(cov_matrix)
## NVDA AMD AC
## NVDA 0.0009817843 0.0007153074 0.0001679087
## AMD 0.0007153074 0.0014124551 0.0001780747
## AC 0.0001679087 0.0001780747 0.0006385676
data <- timeSeries(returns, charvec = index(returns))
spec <- portfolioSpec()
setRiskFreeRate(spec) <- 0.01
setNFrontierPoints(spec) <- 50
efficientFrontier <- portfolioFrontier(data, spec)
minvar_portfolio <- minvariancePortfolio(data, spec)
tangencyPortfolio <- tangencyPortfolio(data, spec)
optimal_weights <- getWeights(tangencyPortfolio)
print(optimal_weights)
## NVDA AMD AC
## 9.999997e-01 2.702695e-07 0.000000e+00
# Agregar CETES (activo libre de riesgo) al portafolio
risk_free_weight <- 0.10
optimal_weights <- (1 - risk_free_weight) * optimal_weights
optimal_weights <- c(optimal_weights, "CETES" = risk_free_weight)
print(optimal_weights)
## NVDA AMD AC CETES
## 8.999998e-01 2.432426e-07 0.000000e+00 1.000000e-01
frontier_points <- data.frame(
Risk = getTargetRisk(efficientFrontier),
Return = getTargetReturn(efficientFrontier)
)
tangency_points <- data.frame(
Risk = sd(portfolioReturn(tangencyPortfolio)),
Return = mean(portfolioReturn(tangencyPortfolio))
)
p1 <- plot_ly(frontier_points, x = ~Risk.Sigma, y = ~Return.mean, type = 'scatter', mode = 'line',
name = 'Frontera Eficiente', line = list(color = 'blue')) %>%
add_trace(data = tangency_points, x = ~Risk, y = ~Return, type = 'scatter', mode = 'markers',
name = 'Portafolio Tangencial', marker = list(color = 'red', size = 10)) %>%
layout(title = "Frontera Eficiente vs Portafolio Tangencial",
xaxis = list(title = "Riesgo (Desviación Estándar)"),
yaxis = list(title = "Rendimiento Esperado"))
p1
## Warning: Ignoring 1 observations
## A line object has been specified, but lines is not in the mode
## Adding lines to the mode...
## A line object has been specified, but lines is not in the mode
## Adding lines to the mode...
minvar_points <- data.frame(
Risk = sd(portfolioReturn(minvar_portfolio)),
Return = mean(portfolioReturn(minvar_portfolio))
)
p2 <- plot_ly(frontier_points, x = ~Risk.Sigma, y = ~Return.mean, type = 'scatter', mode = 'lines',
name = 'Frontera Eficiente', line = list(color = 'blue')) %>%
add_trace(data = minvar_points, x = ~Risk, y = ~Return, type = 'scatter', mode = 'markers',
name = 'Portafolio de Mínima Varianza', marker = list(color = 'green', size = 10)) %>%
layout(title = "Frontera Eficiente vs Portafolio de Mínima Varianza",
xaxis = list(title = "Riesgo (Desviación Estándar)"),
yaxis = list(title = "Rendimiento Esperado"))
p2
## Warning: Ignoring 1 observations
## A line object has been specified, but lines is not in the mode
## Adding lines to the mode...
stats_df_df <- as.data.frame(stats_df)
sharpe_points <- data.frame(
Asset = rownames(stats_df),
SharpeRatio = stats_df_df$SharpeRatio
)
p3 <- plot_ly(frontier_points, x = ~Risk.Sigma, y = ~Return.mean, type = 'scatter', mode = 'lines',
name = 'Frontera Eficiente', line = list(color = 'red'))
# Gráfico del Ratio Sharpe (bar plot)
p4 <- plot_ly(sharpe_points, x = ~Asset, y = ~SharpeRatio, type = 'bar',
name = 'Ratio Sharpe', marker = list(color = 'blue'))
# Combinar los dos gráficos en un layout
p5 <- subplot(p3, p4) %>%
layout(title = "Frontera Eficiente vs Ratio Sharpe",
xaxis = list(title = "Acciones"),
yaxis = list(title = "Valor"))
p5
port_returns <- Return.portfolio(returns, weights = optimal_weights[-length(optimal_weights)])
## Warning in Return.portfolio.geometric(R = R, weights = weights, wealth.index =
## wealth.index, : The weights for one or more periods do not sum up to 1:
## assuming a return of 0 for the residual weights
port_returns <- Return.portfolio(returns, weights = optimal_weights[-length(optimal_weights)])
## Warning in Return.portfolio.geometric(R = R, weights = weights, wealth.index =
## wealth.index, : The weights for one or more periods do not sum up to 1:
## assuming a return of 0 for the residual weights
performance <- merge(port_returns, ipc_returns, join = "inner")
colnames(performance) <- c("Portafolio", "IPC")
charts.PerformanceSummary(performance, main = "Desempeño Histórico del Portafolio vs. IPC")